/*
 * Copyright 2011 Kim Lindhardt Madsen
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package dk.lindhardt.gwt.geie.shared;

import java.io.Serializable;

/**
 * Describes a cells position
 */
public class Position implements Serializable {

   private int row;
   private int column;
   private int spanRow;
   private int spanColumn;
   private boolean hasSpans = false;

   private Position() {
   }

   /**
    * Position with no spanning
    *
    * @param row
    * @param column
    */
   public Position(int row, int column) {
      this.row = row;
      this.column = column;
   }

   /**
    * Position with spanning
    *
    * @param row        most upper row
    * @param column     most right column
    * @param spanRow    number of rows to span
    * @param spanColumn number of columns to span
    */
   public Position(int row, int column, int spanRow, int spanColumn) {
      this.row = row;
      this.column = column;
      this.spanRow = spanRow;
      this.spanColumn = spanColumn;
      if (spanRow > 1 || spanColumn > 1) {
         hasSpans = true;
      }
   }

   /**
    * @return row index
    */
   public int getRow() {
      return row;
   }

   /**
    * @param row row index
    */
   public void setRow(int row) {
      this.row = row;
   }

   /**
    * @return column index
    */
   public int getColumn() {
      return column;
   }

   /**
    * @param column column index
    */
   public void setColumn(int column) {
      this.column = column;
   }

   /**
    * @return number of rows to span
    */
   public int getSpanRow() {
      return spanRow;
   }

   /**
    * @param spanRow number of rows to span
    */
   public void setSpanRow(int spanRow) {
      this.spanRow = spanRow;
      if (spanRow > 1) {
         this.hasSpans = true;
      } else {
         if (spanColumn <= 1) {
            this.hasSpans = false;
         }
      }
   }

   /**
    * @return number columns to span
    */
   public int getSpanColumn() {
      return spanColumn;
   }

   /**
    * @param spanColumn number of column to span
    */
   public void setSpanColumn(int spanColumn) {
      this.spanColumn = spanColumn;
      if (spanColumn > 1) {
         this.hasSpans = true;
      } else {
         if (spanRow <= 1) {
            this.hasSpans = false;
         }
      }
   }

   /**
    * @return does this cell span any column or rows
    */
   boolean isHasSpans() {
      return hasSpans;
   }

   /**
    * Copies this position to a new instance
    * @return the new instance
    */
   public Position copy() {
      return new Position(row, column, spanRow, spanColumn);
   }


   @Override
   public boolean equals(Object o) {
      if (this == o) {
         return true;
      }
      if (o == null || getClass() != o.getClass()) {
         return false;
      }

      Position position = (Position) o;

      if (column != position.column) {
         return false;
      }
      if (row != position.row) {
         return false;
      }
      if (spanColumn > 1 && position.spanColumn > 1 && spanColumn != position.spanColumn) {
         return false;
      }
      if (spanRow > 1 && position.spanRow > 1 && spanRow != position.spanRow) {
         return false;
      }

      return true;
   }

   @Override
   public int hashCode() {
      int result = row;
      result = 31 * result + column;
      result = 31 * result + (spanRow > 1 ? spanRow : 0);
      result = 31 * result + (spanColumn > 1 ? spanColumn : 0);
      return result;
   }

   @Override
   public String toString() {
      if (spanRow > 1 || spanColumn > 1) {
         return "TablePosition(" + row + ", " + column + ", " + spanRow + ", " + spanColumn + ")";
      } else {
         return "TablePosition(" + row + ", " + column + ")";
      }
   }
}